package com.ea.eadp.nexus.test.pageDefinition;

import com.ea.eadp.nexus.test.common.PageOperation;
import com.ea.eadp.nexus.test.common.SystemProperties;
import com.ea.eadp.nexus.test.common.TestUtil;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;
import sun.reflect.generics.reflectiveObjects.NotImplementedException;

public class TwoFactorAuth_Web2 extends BasePage implements TwoFactorAuthClientWithCode<WebDriver> {
    public static final String redirectURI = SystemProperties.instance().getProperty(SystemProperties.LockboxUri);

    public TwoFactorAuth_Web2(WebDriver driver) {
        super(driver, TwoFactorAuth_Web2.class);
        timeout=15;
    }

    public void setTwoFactorCode(String twoFactorCode) {
        driver.switchTo().window(this.operationWindowHandle);
        log.info(twoFactorCode);
        this.waitForWebElementPresent(txtBox_twofactorCode);
        PageOperation.SendKeyToElement(driver, "twofactorCode", twoFactorCode);
    }

    public void clickSubmit() throws Exception {
        clickSubmitWithoutWait();

        WebDriverWait wait = new WebDriverWait(driver, timeout);
        ExpectedCondition e = new ExpectedCondition<Boolean>() {
            @Override
            public Boolean apply(WebDriver d) {
                return (d.getCurrentUrl().contains(redirectURI));
            }
        };
        log.info(driver.getCurrentUrl());
        wait.until(e);
        log.info(driver.getCurrentUrl());
        if (!driver.getCurrentUrl().contains(redirectURI) && !driver.getCurrentUrl().contains("s2")) {
            throw new Exception("validate goes to redirect uri.");
        }
    }

    public void clickSubmitWithoutWait() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        waitForWebElementPresent(btn_submit);
        driver.findElement(btn_submit).click();
    }

    public void clickResendCode() throws Exception {
        driver.switchTo().window(this.operationWindowHandle);
        waitForWebElementPresent(link_resendCode);
        driver.findElement(link_resendCode).click();
    }

    private By btn_submit = By.id("btnTFALogin");
    private By link_resendCode = By.id("resend_code_link");
    private By txtBox_twofactorCode = By.id("twofactorCode");

    @Override
    public WebDriver getClient() {
        return driver;
    }

    @Override
    public void setClient(WebDriver client) {
        throw new UnsupportedOperationException(String.format("client in %s is immutable", getClass().getSimpleName()));
    }

    @Override
    public Status getStatus() throws Exception {
        try {
            driver.findElement(By.id("email"));
            driver.findElement(By.id("password"));
            return Status.REGULAR_AUTH;
        } catch (NoSuchElementException e) {
            // do nothing
        }

        try {
            driver.findElement(txtBox_twofactorCode);
            return Status.CHALLENGING_AUTH;
        } catch (NoSuchElementException e) {
            // do nothing
        }

        return Status.UNKNOWN;
    }

    @Override
    public void goAuthentication() throws Exception {
        SigninPageWeb2 signin_web2 = new SigninPageWeb2(driver);
        signin_web2.navigate();
        signin_web2.waitForWebElementPresent(By.id("email"));
    }

    public void goAuthenticationForSpecific(String clientId) throws Exception {

    }
    public void goAuthenticationForSpecific(String clientId, String redirectUri) throws Exception {

    }

    @Override
    public void login(String username, String password) throws Exception {
        SigninPageWeb2 signin_web2 = new SigninPageWeb2(driver);
        signin_web2.setSigninEmail(username);
        signin_web2.setSigninPassword(password);
        signin_web2.clickToSigninComplete();
    }

    @Override
    public void respondToChallenge(String answer) throws Exception {
        setTwoFactorCode(answer);
        clickSubmit();
    }

    @Override
    public String getInfoMessage() throws Exception {
        try {
            return driver.findElement(By.cssSelector("#mobile-content-login .general-info-banner-tfa")).getText();
        } catch (NoSuchElementException e) {
            return null;
        }
    }

    @Override
    public String getErrorMessage() throws Exception {
        String message = null;

        // specific messages take priority over general message
        try {
            message = driver.findElement(By.id("resend-error-code")).getText();
        } catch (NoSuchElementException e) {
            // do nothing
        }

        try {
            message = driver.findElement(By.cssSelector("#mobile-content-login .general-error")).getText();
        } catch (NoSuchElementException e) {
            // do nothing
        }

        return message;
    }

    @Override
    public void askResendCode() throws Exception {
        clickResendCode();
    }

    @Override
    public void skipUpdateToAppAuth() {
        //To change body of implemented methods use File | Settings | File Templates.
        throw new NotImplementedException();
    }

    @Override
    public void close() throws Exception {
        if (null != driver)
            driver.quit();
    }
}
